/***************************************************************************
 创建者: 华磊
 开始时间: 2018.8.14
 copyright: (C) 华友高科
 修改说明: (每次有修改就添加一条，带有 修改人，修改时间，修改描述)
 example (1) hualei 2017.5.8 类的具体实现代码编写

 ***************************************************************************/
#include "ioinstructionlogic.h"
#include "GeneralDefine.h"
#include "programengine.h"
#include "messagelog.h"


IoInstructionLogic::IoInstructionLogic(int robotIdIn,ProgramSet* programSetIn,
                                       RobotIo* ioControllerIn,ProgramEngine* programEngineIn)
{
    programSet=programSetIn;
    robotId=robotIdIn;
    ioController=ioControllerIn;
    programEngine=programEngineIn;
}

E_PROGRAM_LOOP_RESULT IoInstructionLogic::startIo(int programNum,IoInstruction ioInstruct)
{
    //    qDebug()<<__FUNCTION__<<"**********"<<__LINE__<<"********iO******"<<ioInstruct.type<<endl;

    programEngine->updateProgramSetRegister();

    E_PROGRAM_LOOP_RESULT endFlag = E_PROGRAM_LOOP_RESULT_NORMAL;
    switch(ioInstruct.type)
    {
    case R_DI:
    {
        switch (ioInstruct.back_addtype)
        {
        case DIRECT:
        {
            if(ioInstruct.front_addtype == DIRECT)
            {
                //programSet->r[ioInstruct.front_val] =
            }
            else
            {

            }
            break;
        }
        case INDIRECT:
        {
            if(ioInstruct.front_addtype == DIRECT)
            {
                //programSet->r[ioInstruct.front_val] =
            }
            else
            {

            }
            break;
        }
        }
        break;
    }
    case DO_ON:
    {
        if(ioInstruct.front_addtype == DIRECT)
        {
            int value = ioInstruct.front_val - 1;
            /******************************
                  *给相应的ＩＯ模块赋值
                  * ***************************/

            if( ioController->doCount>value && value >= 0){
                //if(    ioController->lock()  )
              //  {
                    ioController->ioDo[value]=true;
                  //  ioController->unlock();
              //  }
//                else
//                {
//                    qDebug()<<"io 映射錯誤 ！";
//                }
            }else{
                //                QString msg=QObject::tr( "IO毫超出已有逻辑ＩＯ范围，请检查指令或ＩＯ配置，: %1   ").arg( ioController->doCount );
//                MessageLog::getInstance()->addMessage( ENUM_MSG_ERROR,  "ProgramEngine", "ProgramEngine",  3005,  robotId ,  0, 0, 0  );

                addMsg( ENUM_MSG_ERROR, "ProgramEngine", "ProgramEngine",  3005, robotId
                        ,value, ioController->doCount,(*programSet)[programNum].runningLineInt,0,(*programSet)[programNum].thisProgramName);
                programEngine->cmdError(programNum);
                return E_PROGRAM_LOOP_RESULT_ERROR;
            }
        }
        else
        {

        }
        break;
    }
    case DO_OFF:
    {
        if(ioInstruct.front_addtype == DIRECT)
        {
            int value = ioInstruct.front_val - 1;
            /******************************
                  *给相应的ＩＯ模块赋值
                  * ***************************/
            if( ioController->doCount>value  && value >= 0){
              //  if(    ioController->lock()  )
            //    {
                    ioController->ioDo[value]=false;
                  //  ioController->unlock();
          //      }
//                else
//                {
//                    qDebug()<<"io 映射錯誤 ！";
//                }
            }else{
                //                QString msg=QObject::tr( "IO毫超出已有逻辑ＩＯ范围，请检查指令或ＩＯ配置，: %1   ").arg( ioController->doCount );
//                MessageLog::getInstance()->addMessage( ENUM_MSG_ERROR,  "ProgramEngine", "ProgramEngine",  3005,  robotId ,  0, 0, 0  );

                addMsg( ENUM_MSG_ERROR, "ProgramEngine", "ProgramEngine",  3005, robotId
                        ,value, ioController->doCount,(*programSet)[programNum].runningLineInt,0,(*programSet)[programNum].thisProgramName);
                programEngine->cmdError(programNum);
                return E_PROGRAM_LOOP_RESULT_ERROR;
            }
        }
        else
        {
            // R[i]
        }
        break;
    }
    case DO_PULSE_WIDTH:
    {
        switch (ioInstruct.back_addtype)
        {
        case DIRECT:
        {
            if(ioInstruct.front_addtype == DIRECT)
            {
                //programSet->r[ioInstruct.front_val] =
            }
            else
            {

            }
            break;
        }
        case INDIRECT:
        {
            if(ioInstruct.front_addtype == DIRECT)
            {
                //programSet->r[ioInstruct.front_val] =
            }
            else
            {

            }
            break;
        }
        }
        break;
    }
    case DO_R:
    {
        int front_value,back_value;
        float rValue;
        bool doValue;
        if(DIRECT == ioInstruct.front_addtype)
        {
            front_value = ioInstruct.front_val - 1;
        }
        else
        {
            if((ioInstruct.front_val >= 1)&&(programSet->regRList[ioInstruct.front_val - 1]  >= 1)
                    &&(ioInstruct.front_val <= programSet->regRList.size())&&(programSet->regRList[ioInstruct.front_val - 1] <= programSet->regRList.size()))
            {
                front_value = (int)programSet->regRList[ioInstruct.front_val - 1] - 1;
            }
            else
            {
                programEngine->cmdError(programNum);
                addMsg( ENUM_MSG_ERROR, "ProgramEngine", "ProgramEngine",  3017, robotId);
                return E_PROGRAM_LOOP_RESULT_ERROR;
            }
        }

        if(DIRECT == ioInstruct.back_addtype)
        {
            back_value  = ioInstruct.back_val - 1;
        }
        else
        {
            if((ioInstruct.back_val >= 1)
                    &&(ioInstruct.back_val <= programSet->regRList.size()))
            {
                back_value = programSet->regRList[ioInstruct.back_val - 1] - 1;
            }
            else
            {
                programEngine->cmdError(programNum);
                addMsg( ENUM_MSG_ERROR, "ProgramEngine", "ProgramEngine",  3017, robotId);
                return E_PROGRAM_LOOP_RESULT_ERROR;
            }
        }

        if(back_value >= 0 && back_value < programSet->regRList.size())
        {
            rValue = programSet->regRList[back_value];
        }
        else
        {
            programEngine->cmdError(programNum);
            addMsg( ENUM_MSG_ERROR, "ProgramEngine", "ProgramEngine",  3017, robotId);
            return E_PROGRAM_LOOP_RESULT_ERROR;
        }

        if(ZEROMIN < rValue && rValue < ZEROMAX)
        {
            doValue = false;
        }
        else
        {
            doValue = true;
        }

        if( ioController->doCount>front_value && front_value >= 0){
          //  if(    ioController->lock()  )
         //   {
                ioController->ioDo[front_value] = doValue;
                //ioController->unlock();
       //     }
//            else
//            {
//                qDebug()<<"io 映射錯誤 ！";
//            }
        }else{
            //                QString msg=QObject::tr( "IO毫超出已有逻辑ＩＯ范围，请检查指令或ＩＯ配置，: %1   ").arg( ioController->doCount );
//                MessageLog::getInstance()->addMessage( ENUM_MSG_ERROR,  "ProgramEngine", "ProgramEngine",  3005,  robotId ,  0, 0, 0  );

            addMsg( ENUM_MSG_ERROR, "ProgramEngine", "ProgramEngine",  3005, robotId
                    ,front_value, ioController->doCount,(*programSet)[programNum].runningLineInt,0,(*programSet)[programNum].thisProgramName);
            programEngine->cmdError(programNum);
            return E_PROGRAM_LOOP_RESULT_ERROR;
        }

        break;
    }
    case R_RI:
    {
        switch (ioInstruct.back_addtype)
        {
        case DIRECT:
        {
            if(ioInstruct.front_addtype == DIRECT)
            {
                //programSet->r[ioInstruct.front_val] =
            }
            else
            {

            }
            break;
        }
        case INDIRECT:
        {
            if(ioInstruct.front_addtype == DIRECT)
            {
                //programSet->r[ioInstruct.front_val] =
            }
            else
            {

            }
            break;
        }
        }
        break;
    }
    case RO_ON:
    {
        if(ioInstruct.front_addtype == DIRECT)
        {
            //programSet->r[ioInstruct.front_val] =
        }
        else
        {

        }
        break;
    }
    case RO_OFF:
    {
        if(ioInstruct.front_addtype == DIRECT)
        {
            //programSet->r[ioInstruct.front_val] =
        }
        else
        {

        }
        break;
    }
    case RO_PULSE_WIDTH:
    {
        switch (ioInstruct.back_addtype)
        {
        case DIRECT:
        {
            if(ioInstruct.front_addtype == DIRECT)
            {
                //programSet->r[ioInstruct.front_val] =
            }
            else
            {

            }
            break;
        }
        case INDIRECT:
        {
            if(ioInstruct.front_addtype == DIRECT)
            {
                //programSet->r[ioInstruct.front_val] =
            }
            else
            {

            }
            break;
        }
        }
        break;
    }
    case RO_R:
    {
        switch (ioInstruct.back_addtype)
        {
        case DIRECT:
        {
            if(ioInstruct.front_addtype == DIRECT)
            {
                //programSet->r[ioInstruct.front_val] =
            }
            else
            {

            }
            break;
        }
        case INDIRECT:
        {
            if(ioInstruct.front_addtype == DIRECT)
            {
                //programSet->r[ioInstruct.front_val] =
            }
            else
            {

            }
            break;
        }
        }
        break;
    }
    case R_AI:
    {
        switch (ioInstruct.back_addtype)
        {
        case DIRECT:
        {
            if(ioInstruct.front_addtype == DIRECT)
            {
                //programSet->r[ioInstruct.front_val] =
            }
            else
            {

            }
            break;
        }
        case INDIRECT:
        {
            if(ioInstruct.front_addtype == DIRECT)
            {
                //programSet->r[ioInstruct.front_val] =
            }
            else
            {

            }
            break;
        }
        }
        break;
    }
    case AO_CONST:
    {
        if(ioInstruct.front_addtype == DIRECT)
        {
            /******************************
                  *给相应的ＩＯ模块赋值
                  * ***************************/
             int front_value = ioInstruct.front_val - 1;
             int back_value = ioInstruct.back_val;

            if( ioController->aoCount>front_value  && front_value >= 0)
            {
//                if( ioController->lock()  )
//                {
                    ioController->ioAo[front_value] = back_value;
//                    ioController->unlock();
//                }
//                else
//                {
//                    qDebug()<<"io 映射錯誤 ！";
//                }
            }
            else
            {

                addMsg( ENUM_MSG_ERROR, "ProgramEngine", "ProgramEngine",  3005, robotId
                        , front_value, ioController->aoCount,(*programSet)[programNum].runningLineInt,0,(*programSet)[programNum].thisProgramName);
                programEngine->cmdError(programNum);
                return E_PROGRAM_LOOP_RESULT_ERROR;
            }
        }
        else
        {

        }
        break;
    }
    case AO_R:
    {
        switch (ioInstruct.back_addtype)
        {
        case DIRECT:
        {
            if(ioInstruct.front_addtype == DIRECT)
            {
                //programSet->r[ioInstruct.front_val] =
            }
            else
            {

            }
            break;
        }
        case INDIRECT:
        {
            if(ioInstruct.front_addtype == DIRECT)
            {
                //programSet->r[ioInstruct.front_val] =
            }
            else
            {

            }
            break;
        }
        }
        break;
    }
    case R_GI:
    {
        switch (ioInstruct.back_addtype)
        {
        case DIRECT:
        {
            if(ioInstruct.front_addtype == DIRECT)
            {
                //programSet->r[ioInstruct.front_val] =
            }
            else
            {

            }
            break;
        }
        case INDIRECT:
        {
            if(ioInstruct.front_addtype == DIRECT)
            {
                //programSet->r[ioInstruct.front_val] =
            }
            else
            {

            }
            break;
        }
        }
        break;
    }
    case GO_CONST:
    {
        if(ioInstruct.front_addtype == DIRECT)
        {
            //programSet->r[ioInstruct.front_val] =
        }
        else
        {

        }
        break;
    }
    case GO_R:
    {
        switch (ioInstruct.back_addtype)
        {
        case DIRECT:
        {
            if(ioInstruct.front_addtype == DIRECT)
            {
                //programSet->r[ioInstruct.front_val] =
            }
            else
            {

            }
            break;
        }
        case INDIRECT:
        {
            if(ioInstruct.front_addtype == DIRECT)
            {
                //programSet->r[ioInstruct.front_val] =
            }
            else
            {

            }
            break;
        }
        }
        break;
    }

    default:
        break;
    }

    programEngine->calculateNextLineToRun(programNum);

    endFlag = programEngine->isTheLastInstruction(programNum);
    return endFlag;

    //qDebug() << "startIo********programSet.pc"<<(*programSet)[programNum].pc<<"programNum***********"<<programNum<<endl;
}


void IoInstructionLogic::addMsg(int messageLevel, string componentName, string messageType,
                           int messageCode, int robotId,
                           int parameter1, int parameter2, int parameter3, int parameter4,QString message)
{
    Message tmpMsg;
    tmpMsg.MessageLevel = messageLevel;
    tmpMsg.componentClassName = componentName;
    tmpMsg.messageType = messageType;
    tmpMsg.robotId = robotId;
    tmpMsg.messageCode = messageCode;
   // tmpMsg.time = t1.tv_sec;


    QString infomationStr;

    switch(messageCode)
    {

    case 3005:
    {
        infomationStr =  QObject::tr("机器人:")  + QString::number(robotId);
        infomationStr = infomationStr + QObject::tr("; %1,第%2行， IO号超出已有逻辑ＩＯ范围，请检查指令或ＩＯ配置，").arg(message).arg(parameter3)
                +QString::number(parameter1) + ">="
        +QString::number(parameter2);
        break;


    }
    case 3017:
    {
        infomationStr =  QObject::tr("机器人:")  + QString::number(robotId);
        infomationStr = infomationStr + QObject::tr(",寄存器指令错误，寄存器的范围超过限定的最大范围，请修改")+message;
    }
        break;



    default:
    {

    }
    }


    tmpMsg.MessageInformation = infomationStr.toStdString();

    // qDebug()<<"53444444444444444444444"<< tmpMsg.messageCode;
    MessageLog::getInstance()->addMessage(tmpMsg);
}
